#include <Windows.h>
#include <Windowsx.h>
#include <tchar.h>
#include "resource.h"

struct SThreadInfo
{
	HWND	hList;
	DWORD	nMax;
	HANDLE	hSemaphore;
};

DWORD CALLBACK ThreadProc(LPVOID lpData)
{
	SThreadInfo* threadInfo = (SThreadInfo*)lpData;
	bool bStop = false;
	while (!bStop)
	{
		DWORD dwWait = WaitForSingleObject(threadInfo->hSemaphore, 0);
		switch (dwWait)
		{
			case WAIT_OBJECT_0:
			{
				TCHAR szTmp[128];
				for (int ii = 0; ii < threadInfo->nMax; ii++)
				{
					_stprintf(szTmp, _T("print %03d lines"), ii + 1);
					Sleep(5);
					ListBox_AddString(threadInfo->hList, szTmp);
					SendMessage(threadInfo->hList, WM_VSCROLL, SB_BOTTOM, 0);
				}
				bStop = true;
				LONG nPreCount = 0;
				ReleaseSemaphore(threadInfo->hSemaphore, 1, &nPreCount);
				
				break;
			}	
			case WAIT_TIMEOUT:
			{
				break;
			}
		}
	}

	return 0;
}

int CALLBACK DlgProc(HWND hDlg, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
	static SThreadInfo threadInfo[8];
	static HANDLE hSemaphore;
	switch (nMsg)
	{
		case WM_INITDIALOG:
		{
			SetWindowText(hDlg, _T("Demo0092"));

			UINT nWidth		= GetSystemMetrics(SM_CXSCREEN);
			UINT nHeight	= GetSystemMetrics(SM_CYSCREEN);
			RECT rtClient;
			GetClientRect(hDlg, &rtClient);
			SetWindowPos(hDlg, NULL, (nWidth - (rtClient.right - rtClient.left)) / 2, (nHeight - (rtClient.bottom - rtClient.top)) / 2, 0, 0, SWP_NOSIZE);
		
			hSemaphore	= CreateSemaphore(NULL, 2, 8, NULL);

			break;
		}
		case WM_COMMAND:
		{
			switch (LOWORD(wParam))
			{
				case IDC_BTNSTART:
				{
					struct SParam {
						DWORD dwID;
						DWORD nMax;
					};
					static SParam Param[] = {
						{IDC_LIST1, 100}, {IDC_LIST2, 700}, {IDC_LIST3, 300}, {IDC_LIST4, 500},
 					    {IDC_LIST5, 600}, {IDC_LIST6, 400}, {IDC_LIST7, 200}, {IDC_LIST8, 300}
					};

					for (int ii = 0; ii < 8; ii++)
					{
						HWND hList = GetDlgItem(hDlg, Param[ii].dwID);
						for (int jj = ListBox_GetCount(hList); jj >= 0; jj--)
						{
							ListBox_DeleteString(hList, jj);
						}
					}

					for (int ii = 0; ii < 8; ii++)
					{
						threadInfo[ii].hList		= GetDlgItem(hDlg, Param[ii].dwID);
						threadInfo[ii].nMax			= Param[ii].nMax;
						threadInfo[ii].hSemaphore	= hSemaphore;
						CreateThread(NULL, 0, ThreadProc, (LPVOID)&threadInfo[ii], NULL, NULL);
					}

					break;
				}
			}
			break;
		}
		case WM_CLOSE:
		{
			CloseHandle(threadInfo->hSemaphore);

			PostQuitMessage(0);
			break;
		}
	}

	return 0;
}

BOOL WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPTSTR szCmdLine, int nShowCmd)
{
	DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG), NULL, DlgProc);

	return TRUE;
}